package com.sihan.framework.etm.service.baseData.impl;

import com.framework.exception.BusinessException;
import com.framework.model.ApiResult;
import com.framework.model.PageResult;
import com.framework.mybatis.service.impl.BaseServiceImpl;
import com.framework.util.PageUtils;
import com.framework.util.WebUtils;
import com.github.pagehelper.PageHelper;
import com.sihan.framework.etm.common.AppConfiguration;
import com.sihan.framework.etm.common.CacheOperatorInfo;
import com.sihan.framework.etm.common.CommonBiz;
import com.sihan.framework.etm.dto.baseData.ToolDTO;
import com.sihan.framework.etm.entity.baseData.ToolBindDeviceRecord;
import com.sihan.framework.etm.entity.baseData.ToolModel;
import com.sihan.framework.etm.enums.CacheKeyName;
import com.sihan.framework.etm.mapper.baseData.ToolDeviceBindMapper;
import com.sihan.framework.etm.mapper.baseData.ToolMapper;
import com.sihan.framework.etm.service.baseData.ToolService;
import com.sihan.framework.etm.vo.baseData.ToolVO;
import com.sihan.framework.etm.vo.business.ToolOverviewVO;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@Slf4j
public class ToolServiceImpl extends BaseServiceImpl<ToolModel, String> implements ToolService {

	@Autowired
	private ToolMapper toolMapper;
	
	@Autowired
	private ToolDeviceBindMapper toolDeviceBindMapper;
	
	@Autowired
	private CommonBiz commonBiz;
	
	@Autowired
	private AppConfiguration appConfig;

	@Override
	public PageResult<ToolVO> selectPage(ToolDTO dto) {
		if(!StringUtils.isBlank(dto.getQueryStartTime())) {
			dto.setQueryStartTime(dto.getQueryStartTime() + " 00:00:00:000");
		}
		if(!StringUtils.isBlank(dto.getQueryEndTime())) {
			dto.setQueryEndTime(dto.getQueryEndTime() + " 23:59:59:999");
		}
	    PageHelper.startPage(dto);
	    List<ToolVO> result = toolMapper.selectPage(dto);
	    return PageUtils.toPageResult(result);
	}
	
	@Override
	public void bindOrUnbindDevice(String toolId, String deviceId, Integer type) {
		ToolModel tool = toolMapper.selectById(toolId);
		if(null != type) {
			ToolBindDeviceRecord record = new ToolBindDeviceRecord();
			record.setCreateTime(new Date());
			record.setCreateUser(WebUtils.username());
			record.setToolId(toolId);
			if(type == 1) {
				tool.setBindDeviceId(deviceId);
				tool.setIsBind(1);
				record.setOperatorType(1);
				record.setDeviceId(deviceId);
			}else if(type == 0){
				tool.setBindDeviceId(null);
				tool.setIsBind(0);
			}
			tool.setLastUpdateTime(new Date());
			tool.setLastUpdateUser(WebUtils.username());
			tool.setBindTime(new Date());
			toolDeviceBindMapper.insert(record);
			toolMapper.updateById(tool);
		}
	}

	@Override
	public List<Map<String, String>> selectAll() {
		return toolMapper.selectAll();
	}

	@Override
	public ToolVO findById(String id) {
		ToolVO vo = toolMapper.findById(id);
		if(null != vo) {
			if(!StringUtils.isBlank(vo.getManufactorDate())) {
				vo.setManufactorDate(vo.getManufactorDate().substring(0,10));
			}
			if(!StringUtils.isBlank(vo.getTestDate())) {
				vo.setTestDate(vo.getTestDate().substring(0,10));
			}
			if(!StringUtils.isBlank(vo.getExpiredDate())) {
				vo.setExpiredDate(vo.getExpiredDate().substring(0,10));
			}
			if(!StringUtils.isBlank(vo.getBuyDate())) {
				vo.setBuyDate(vo.getBuyDate().substring(0,10));
			}
			if(!StringUtils.isBlank(vo.getCreateTime())) {
				vo.setCreateTime(vo.getCreateTime().substring(0,19));
			}
		}
		return vo;
	}

	@Override
	public void update(ToolOverviewVO param) {
		ToolModel tool = toolMapper.selectById(param.getToolId());
		if(null == tool) {
			throw new BusinessException("更新失败");
		}
		
		int duplicateToolName = toolMapper.checkToolNameHasDuplicate(tool.getId(), tool.getStandardId(), param.getToolName());
//		
		if(duplicateToolName > 0) {
			throw new BusinessException("工器具编号重复!");
		}
//		if(param.getTypeId() == null) {
//			throw new BusinessException("请选择工器具类型");
//		}
		
		if(param.getNeedBind()) {
			CacheOperatorInfo.setMapValue(CacheKeyName.READER_LOG.getValue(), CacheOperatorInfo.TOOL_CODE_READ_FLAG_UPDATE);
			CacheOperatorInfo.setMapValue(CacheKeyName.READER_CODE_LIST.getValue(), 
					CacheKeyName.READER_CODE_LIST.getValue());
			commonBiz.sendIvgScanStartCommand();
			Boolean hasExpired = false;
			Date d = new Date();
			Boolean hasDone = false;
			String oldCode = "";
			while(!hasDone && !hasExpired) {
				oldCode = (String)CacheOperatorInfo.getMapValue(CacheKeyName.READER_CODE_LIST.getValue(), 
						CacheKeyName.READER_CODE_LIST.getValue());
				if(!StringUtils.isBlank(oldCode) && !oldCode.equals(CacheKeyName.READER_CODE_LIST.getValue())) {
					hasDone = true;
				}
				Calendar c = Calendar.getInstance();
				c.add(Calendar.SECOND, -appConfig.getWaitSeconds());
				if(c.getTime().compareTo(d) >= 0) {
					hasExpired = true;
				}
			}
			
			if(hasExpired) {
				commonBiz.sendIvgScanStopCommand();
				throw new BusinessException("请将工器具放置读写区域");
			}
			
			if(!StringUtils.isBlank(oldCode) && !oldCode.equals(CacheKeyName.READER_CODE_LIST.getValue())) {
				if(oldCode.split(",").length > 1) {
					commonBiz.sendIvgScanStopCommand();
					throw new BusinessException("一次只能修改一个工器具");
				}
			}
			
			String tid = (String)CacheOperatorInfo.getMapValue(CacheKeyName.TID_VALUE.getValue(), CacheKeyName.TID_VALUE.getValue());
			
			if(!StringUtils.isBlank(tid) && !tid.equals(CacheKeyName.TID_VALUE.getValue())) {
				commonBiz.sendIvgScanStopCommand();
				Boolean setResult = commonBiz.sendSetCodeCommand(tid,tool.getCode());
				log.info("下发设置工器具编号命令：tid="+tid+",code="+tool.getCode());
				if(!setResult) {
					//重试一次
					setResult = commonBiz.sendSetCodeCommand(tid,tool.getCode());
					if(!setResult) {
						throw new BusinessException("设置工器具编号失败，请重试");
					}
				}
			}
			tool.setName(param.getToolName2());
			toolMapper.updateById(tool);
		}
	}

	@Override
	public ApiResult<?> rfidUnbind(String id) {
		ToolModel tool = toolMapper.selectById(id);
		if(null == tool) {
			return ApiResult.fail("未查询到工器具");
		}
		toolMapper.updateRfidUnbind(id);
		return ApiResult.success();
	}

}
